<template>
    <el-dialog title="添加身份" v-model="open" width="500">

        <el-form :model="formItem" label-width="auto">
            <el-form-item label="角色名称">
                <el-input v-model="formItem.name" clearable />
            </el-form-item>
            <el-form-item label="是否开启">
                <el-radio-group v-model="formItem.state">
                    <el-radio label="开启" :value="1"></el-radio>
                    <el-radio label="关闭" :value="0"></el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="权限">
                <div class="flex-bt" style="width: 100%; height: 260px; align-items: flex-start;">
                    <!-- 权限树形控件 -->
                    <div style="overflow-y: scroll;width: 100%; height: 100%;">
                        <el-tree ref="treeRef" v-model="formItem.permissionIds" show-checkbox
                            :data="permissionData.rows" node-key="_id" :props="{ label: 'title' }"
                            :check-strictly="true" @check="handleCheckChange" />
                    </div>
                    <el-button type="primary" link @click="onExpandToggle">{{ isExpand ? '收起' : '展开' }}</el-button>
                </div>
            </el-form-item>
        </el-form>


        <template #footer>
            <el-button @click="open = false">取消</el-button>
            <el-button type="primary" @click="onConfirm">确认</el-button>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { addRoleApi, updateRoleApi } from '@/api/role';
import { useFindData } from '@/composables/findData';
import { nextTick, onMounted, ref, useTemplateRef, watch } from 'vue';
import type { TreeInstance } from 'element-plus'
const emit = defineEmits(['findRole'])
const open = ref(false);
const formItem = ref<any>({})
const isExpand = ref(false);
const treeRef = useTemplateRef<TreeInstance>('treeRef')

const { findPermissionAsync, permissionData } = useFindData();

onMounted(() => {
    findPermissionAsync({ creator: 'jianglan' });
})

// 一键展开收起
const onExpandToggle = () => {
    isExpand.value = !isExpand.value;
}
watch([isExpand, treeRef], () => {
    treeRef.value?.store._getAllNodes().forEach(node => {
        node.expanded = isExpand.value;
    })
})

// --------------------------- Tree组件的父子联动勾选功能 -----------------------------
// 当用户点击Tree组件中的复选框时，触发该事件
const handleCheckChange = (node: any, checkedStatus: any) => {
    // 判断选中的数组中是否有当前点击的节点
    const checked = checkedStatus.checkedKeys.includes(node._id);
    // 进入if，说明用户当前的操作是【勾选】
    if (checked) {
        // 选中节点时处理子节点和父节点
        if (node.children?.length) {
            // 勾选所有子节点
            checkAllChildren(node, true);
        }
        checkAllParents(node);
    } else {
        // 取消节点时处理子节点
        if (node.children?.length) {
            checkAllChildren(node, false);
        }
    }
}
// 递归操作子节点
const checkAllChildren = (node: any, checked: boolean) => {
    node.children.forEach((child: any) => {
        treeRef.value?.setChecked(child._id, checked, false);
        if (child.children) checkAllChildren(child, checked);
    });
}
// 递归操作父节点
const checkAllParents = (node: any) => {
    let parent = getParentNode(node);
    while (parent) {
        treeRef.value?.setChecked(parent._id, true, false);
        parent = getParentNode(parent);
    }
}
// 父节点查找算法，返回目标节点的直接父节点
const getParentNode = (node: any) => {
    const findParent = (data: any[], targetId: string, parent: any): any => {
        for (const item of data) {
            if (item._id === targetId) return parent;
            if (item.children) {
                const found = findParent(item.children, targetId, item);
                if (found) return found;
            }
        }
        return null;
    }
    return findParent(permissionData.rows, node._id, null);
}
// ------------------------- Tree组件的父子联动勾选功能 --------------------------------


function onConfirm() {
    if (formItem.value._id) {
        updateRole();
    } else {
        addRole();
    }
}

async function addRole() {
    // !感叹号表示：非空断言，断定感叹号前面的数据不是 null 或 undefined
    // console.log(treeRef.value!.getCheckedKeys(false));
    const res = await addRoleApi({
        ...formItem.value,
        permissionIds: treeRef.value!.getCheckedKeys(false)
    })
    if (res.code == 200) {
        open.value = false;
        ElMessage.success('权限数据添加成功');
        // 新数据添加成功后，需要重新向后端发送请求获取最新的表格数据
        // findPermissionAsync({ creator: 'jianglan' })
        emit('findRole');
    } else {
        ElMessage.error(res.message);
    }

}
async function updateRole() {
    const res = await updateRoleApi({
        ...formItem.value,
        permissionIds: treeRef.value!.getCheckedKeys(false)
    })
    if (res.code == 200) {
        open.value = false;
        ElMessage.success('权限数据修改成功');
        // 新数据添加成功后，需要重新向后端发送请求获取最新的表格数据
        // findPermissionAsync({ creator: 'jianglan' })
        emit('findRole');
    } else {
        ElMessage.error(res.message);
    }
}

function openDialog(updateItem?: any) {
    open.value = true;
    if (updateItem) {
        // 修改
        // formItem.value = { ...updateItem };
        // 将要修改的数据，保存到表单对象身上
        formItem.value = {
            ...updateItem,
            permissionIds: updateItem.permissionIds.map((item: any) => item._id)
        }

        nextTick(() => {
            // nextTick内部的箭头函数，会在页面标签组件挂载渲染完成后才执行

            // 调用Tree组件的setCheckedKeys方法，来设置默认选中
            treeRef.value?.setCheckedKeys(formItem.value.permissionIds, false);
        })

        isExpand.value = true;

    } else {
        // 新增
        formItem.value = {};
    }

}

defineExpose({
    openDialog
})
</script>

<style scoped></style>